'''
Copyright: 
Descripttion: 
version: 
Author: chengx
Date: 2021-05-22 19:58:31
LastEditors: chengx
LastEditTime: 2021-07-16 09:57:31
'''
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import  pyqtSignal,QThread,QObject
from PyQt5.QtGui import QIcon
import ui
from progressBar import my_Circle
import scipy.io
import numpy as np
import cv2
from FCM_ABC_BS.myFCM import myFCM
from FCM_ABC_BS.myABC import ABC
from ICA.myICA import myIcaBs
from CLASSFICATION.mysvm import svmRun,creatResultImage

im = scipy.io.loadmat('./HSI/PaviaU.mat')['paviaU']
imGIS = scipy.io.loadmat('./HSI/PaviaU_gt.mat')['paviaU_gt']

class MainCode(ui.UI_BandSelection):

    output_sig = pyqtSignal(str) #输出框输出
    abcBs_sig = pyqtSignal(np.ndarray) # FCM ABC BS 信号
    icaBs_sig = pyqtSignal(np.ndarray) # ICA BS 信号
    class_sig = pyqtSignal(np.ndarray,np.ndarray,np.ndarray) # 开始分类信号
    grayPicShow_sig = pyqtSignal()  #显示灰度图
    rgbPicShow_sig = pyqtSignal()   # 显示结果伪彩色图

    def __init__(self):
        ui.UI_BandSelection.__init__(self)
        self.w = my_Circle()

        self.loadBtn.clicked.connect(self.loadHSI)
        self.runBtn.clicked.connect(self.classHSI)
        self.taskName.currentTextChanged.connect(self._comboBox_Changed)
        
        self.output_sig.connect(self.show_massage)
        self.grayPicShow_sig.connect(self.show_grayImage)
        self.rgbPicShow_sig.connect(self.show_rgbImage)

        self.creatThread()
        self.bandInd = np.zeros(15) #<class 'NoneType'>
        self.bsMethod = '全波段'


    def loadHSI(self): # 加载高光谱图像
        global im, imGIS

        x = im.copy()
        y = imGIS.copy()

        # 归一化 
        x = (x - float(np.min(x)))
        x = x/np.max(x)

        img = (x[:,:,50].reshape(-1)*50+40).reshape(x.shape[0], x.shape[1])
        cv2.imwrite('./gray.jpg',img)

        x = np.reshape(x,(x.shape[0]*x.shape[1],x.shape[2]))
        y = y.reshape(y.shape[0]*y.shape[1])



        pos = np.where(y==0)
        self.label = np.delete(y,pos)
        self.data = np.delete(x,pos,axis=0)
        
        self.grayPicShow_sig.emit()
        print('read hsi shape is',self.data.shape,self.label.shape)
        
        return self.data,self.label

    def icaBs(self):
        # print("icaBs id"+str(int(QThread.currentThreadId())))
        self.icaBs_sig.emit(self.data)# 发出BS信号
        # print('sig emit success!')
        self.output_sig.emit('icaBs runing...')

    def FcmAbcBs(self):
        # print("FcmAbcBs id"+str(int(QThread.currentThreadId())))
        self.abcBs_sig.emit(self.data)# 发出BS信号
        # print('sig emit success!')
        self.output_sig.emit('FcmAbcBs runing...')

    def BsResultShow(self,msg):# 输出框显示波段选择的结果
        self.bandInd = msg
        self.output_sig.emit(str(msg))

    def ClResultShow(self,msg):# 输出框显示分类的OA
        msg = self.bsMethod+' OA: '+str(msg)
        self.output_sig.emit(msg)
        self.rgbPicShow_sig.emit()

    def _comboBox_Changed(self,itemName): # 选择不同的波段选择算法
        self.bsMethod = itemName

        if self.taskName.currentText() == 'ABC':
            print('人工蜂群')
            self.FcmAbcBs()
        elif self.taskName.currentText() == 'ICA':
            print('独立成分分析')
            self.icaBs()

    def classHSI(self): # 分类
        self.output_sig.emit('分类任务运行中...')
        self.class_sig.emit(self.data,self.label,self.bandInd)
        self.bandInd = np.zeros(15) # 分类信号没发送一次 波段归零一次

    def creatThread(self):
        self.band_select_Thread = QThread()
        self.band_select_proce = bandSelect()
        self.band_select_proce.moveToThread(self.band_select_Thread)
        self.abcBs_sig.connect(self.band_select_proce.abcBs)
        self.icaBs_sig.connect(self.band_select_proce.icaBs)
        self.class_sig.connect(self.band_select_proce.classification)
        self.band_select_proce.progress_start_sig.connect(self.showProgress)
        self.band_select_proce.progress_close_sig.connect(self.w.close)
        self.band_select_proce.resultBS_sig.connect(self.BsResultShow)# 传递回BS结果
        self.band_select_proce.resultCL_sig.connect(self.ClResultShow)# 传递回分类结果
        self.band_select_Thread.start()

    def showProgress(self):
        self.w.show()


# 开子线程做波段选择和分类
class bandSelect(QObject):#开子线程做数据处理

    progress_start_sig = pyqtSignal()#进度条更新信号
    progress_close_sig = pyqtSignal()#进度条关闭信号
    resultBS_sig = pyqtSignal(np.ndarray) # 输出波段选择结果
    resultCL_sig = pyqtSignal(float) # 输出分类OA

    def abcBs(self,data):
        # print("run abcBs id"+str(int(QThread.currentThreadId())))
        #FCM 聚类，abc做波段选择
        print('FCM runing...')
        index,count = myFCM(data,15,2)#FCM 做聚类分析
        print(index)
        print('ABC runing... ')
        myabc = ABC(data,15,index)#ABC 做组合优化
        myabc.initParams()
        bestBands = myabc.run() # np
        self.resultBS_sig.emit(bestBands)
        # print('the best bands group:',bestBands)
        print('abcBs finish')

    def icaBs(self,data):
        # print("run ica id"+str(int(QThread.currentThreadId())))
        bestBands = myIcaBs(data) # np
        self.resultBS_sig.emit(bestBands)
        # print('the best bands group:',bestBands)
        print('icaBs finish')
    
    def classification(self,x,y,index):
        global im, imGIS
        self.progress_start_sig.emit()
        # 归一化 
        im = (im - float(np.min(x)))
        im = im/np.max(im)
        index = index.astype(int)
        print(index.shape,index,type(index[0]))
        OA,model = svmRun(x,y,index)

        print('预测结束,开始生成伪彩图...')

        if index.sum() != 0:
            im_ = im[:,:,index]
        else:
            im_ = im
        creatResultImage(im_, imGIS,model) # 预测每一点

        self.resultCL_sig.emit(OA)
        self.progress_close_sig.emit()


if __name__=='__main__':
    app=QApplication(sys.argv)
    md=MainCode()
    md.show()
    sys.exit(app.exec_())